<?php

/**
 * This is the model class for table "users".
 *
 * The followings are the available columns in table 'users':
 * @property integer $user_id
 * @property string $username
 * @property string $email
 * @property string $password
 * @property string $salt
 * @property string $display_name
 * @property string $activation_key
 * @property string $type
 * @property integer $status
 * @property integer $joined
 * @property string $first_name
 * @property string $last_name
 * @property string $gender
 * @property string $social_provider
 * @property string $social_uid
 * @property string $access_token
 * @property string $bio
 * @property integer $last_login_time
 * @property string $last_login_ip
 * @property string $country
 * @property string $state
 * @property string $city
 * @property string $address
 * @property string $phone
 * @property string $telephone
 * @property string $mobile
 * @property string $postcode
 * @property integer $featured
 * @property string $avatar
 * @property string $webpage
 * @property string $timezone
 * @property string $language
 * @property int $marital
 * @property int $ethnicity
 * @property int $relationship
 * @property int $zodiac
 * @property int $smoking
 * @property int $height 
 * @property int $general_build
 * @property int $children
 * @property int $religion
 * @property int $more_info
 * @property int $age
 * @property int $birthday
 * 
 * 
 * The followings are the available model relations:
 * @property Posts[] $posts
 */
class User extends CActiveRecord {

    /**
     * hold the password after find
     * @var string
     */
    public $initialPassword;

    /**
     * password required when change or create new
     * @var string
     */
    public $repassword;
    public $re_email;
    public $oldpass;
    public $ideal_profile;

    const STATUS_WAITING_ACTIVE = 0;
    const STATUS_ACTIVE = 1;
    const STATUS_SUSPENDED = 2;
    const GENDER_FEMALE = 'female';
    const GENDER_MALE = 'male';
    const LIMIT_NAME = 12;
    const TOTAL_RECORD = 6;
    /**
     * define user type
     */
    const TYPE_SUPER_ADMIN = 'supperAdmin';
    const TYPE_ADMIN = 'admin';
    const TYPE_MEMBER = 'member';
    const NOT_SEND_MAIL = 0;
    const SEND_MAIL = 1;

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return User the static model class
     */
    public static function model($className = __CLASS__) {
	return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName() {
	return '{{users}}';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
	// NOTE: you should only define rules for those attributes that
	// will receive user inputs.
	return array(
	    array('email, password, username, gender, postcode', 'required', 'on' => 'insert'),
	    array('username, email', 'unique'),
	    array('email', 'email'),
	    array('password, repassword, oldpass', 'length', 'max' => 50, 'min' => 6),
	    array('gender', 'in', 'range' => array(self::GENDER_FEMALE, self::GENDER_MALE)),
	    array('user_id, status, joined, last_login_time, featured', 'numerical', 'integerOnly' => true),
	    array('email, salt , activation_key', 'length', 'max' => 128),
	    array('display_name', 'length', 'max' => 18),
	    array('type, first_name, last_name, social_provider, last_login_ip, username', 'length', 'max' => 25),
	    array('gender', 'length', 'max' => 6),
	    array('social_uid, access_token, address, avatar, webpage', 'length', 'max' => 255),
	    array('country, state, city, telephone, mobile, timezone', 'length', 'max' => 45),
	    array('phone, postcode', 'length', 'max' => 15),
	    array('language', 'length', 'max' => 10),
	    array('bio, repassword, background_header, background_body', 'safe'),
	    // The following rule is used by search().
	    // Please remove those attributes that should not be searched.
	    array('avatar, user_id, email, password, salt, display_name, type, status, joined, first_name, last_name, gender, social_provider, social_uid, access_token, bio, country, state, city, address, phone, telephone, mobile, postcode, webpage, language', 'safe', 'on' => 'search'),
	    //edit
	    array('email, postcode', 'required', 'on' => 'edit_account'),
	    array('oldpass', 'checkCorrectPass', 'on' => 'edit_account'),
	    array('repassword', 'compare', 'compareAttribute' => 'password', 'on' => 'edit_account'),
	    array('username, marital, ethnicity, relationship, zodiac, smoking, height, general_build, children, religion, more_info, age, birthday,ideal_profile, expired_time_msg, is_send_mail, is_send_mail_before', 'safe')
	);
    }

    /**
     * check
     */
    public function checkCorrectPass($attribute, $param) {
	if ($this->{$attribute}) {
	    if (!user()->getModel()->validatePassword($this->{$attribute})) {
		$this->addError($attribute, 'Your old password is not match');
	    }
	}
    }

    /**
     * @return array relational rules.
     */
    public function relations() {
	// NOTE: you may need to adjust the relation name and the related
	// class name for the relations automatically generated below.
	return array(
	    'posts' => array(self::HAS_MANY, 'Posts', 'user_id'),
	    'discussion' => array(self::HAS_MANY, 'Discussion', 'user_id')
	);
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
	return array(
	    'user_id' => 'ID',
	    'username' => 'Username',
	    'email' => 'Email',
	    'password' => 'Password',
	    'repassword' => 'Re-password',
	    'salt' => 'Salt',
	    'display_name' => 'Display Name',
	    'activation_key' => 'Activation Key',
	    'type' => 'Type',
	    'status' => 'Status',
	    'joined' => 'Joined',
	    'first_name' => 'First Name',
	    'last_name' => 'Last Name',
	    'gender' => 'Gender',
	    'social_provider' => 'Social Provider',
	    'social_uid' => 'Social Uid',
	    'access_token' => 'Access Token',
	    'bio' => 'Bio',
	    'last_login_time' => 'Last Login Time',
	    'last_login_ip' => 'Last Login Ip',
	    'country' => 'Country',
	    'state' => 'State',
	    'city' => 'City',
	    'Street' => 'Address',
	    'phone' => 'Phone',
	    'telephone' => 'Telephone',
	    'mobile' => 'Mobile',
	    'postcode' => 'Postcode',
	    'featured' => 'Featured',
	    'avatar' => 'Avatar',
	    'webpage' => 'Webpage',
	    'timezone' => 'Timezone',
	    'language' => 'Language',
	);
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search() {
	// Warning: Please modify the following code to remove attributes that
	// should not be searched.

	$criteria = new CDbCriteria;
	$criteria->compare('user_id', $this->user_id);
	$criteria->compare('email', $this->email, true);
	$criteria->compare('username', $this->username, true);
	$criteria->compare('status', $this->status);

	return new CActiveDataProvider($this, array(
	    'criteria' => $criteria,
	    'pagination' => array(
		'pageSize' => param('pageSize')
	    ),
	    'sort' => array(
		'defaultOrder' => array(
		    'user_id' => CSort::SORT_DESC
		)
	    )
	));
    }

    /**
     * before save check is new user then update user register date
     * @return boolean
     */
    public function beforeSave() {
	if (parent::beforeSave()) {
	    if ($this->isNewRecord) {
		$this->joined = time();

		//check
		if ($this->scenario == 'insert') {
		    //create random salt
		    $this->salt = $this->__generateSalt();
		}
	    } else {
		
	    }

	    // in this case, we will use the old hashed password.
	    if (empty($this->password) && empty($this->repassword) && !empty($this->initialPassword))
		$this->password = $this->repassword = $this->initialPassword;
	    else
		$this->password = $this->hashPassword($this->password, $this->salt);

	    return TRUE;
	}
	return FALSE;
    }

    /**
     * action after save
     */
    public function afterSave() {
	parent::afterSave();
	//reset the password
	$this->password = $this->repassword = NULL;

	//send mail to user signed up
    }

    /**
     * action after find result
     */
    public function afterFind() {
	//reset the password to null because we don't want the hash to be shown.
	$this->initialPassword = $this->password;
	$this->password = null;
	$this->more_info = unserialize($this->more_info);
	parent::afterFind();
    }

    /**
     * Checks if the given password is correct.
     * @param string the password to be validated
     * @return boolean whether the password is valid
     */
    public function validatePassword($password) {
	return $this->hashPassword($password, $this->salt) === $this->initialPassword;
    }

    /**
     * Generates the password hash.
     * @param string password
     * @param string salt
     * @return string hash
     */
    public function hashPassword($password, $salt) {
	return md5($salt . $password);
    }

    /**
     * Generates a salt that can be used to generate a password hash.
     * @return string the salt
     */
    protected function __generateSalt() {
	return uniqid('', true);
    }

    /**
     * get text of status
     * @return string
     */
    public function getStatusText() {
	switch ($this->status) {
	    case self::STATUS_ACTIVE :
		$return = 'Actived';
		break;
	    case self::STATUS_SUSPENDED :
		$return = 'Suspended';
		break;
	    case self::STATUS_WAITING_ACTIVE :
		$return = 'Waiting to active';
		break;
	    default :
		$return = 'Undefined';
		break;
	}

	return $return;
    }

    /**
     * get range status allow
     * @return array $status_key => $text
     */
    public static function getStatusRange() {
	return array(
	    self::STATUS_WAITING_ACTIVE => 'Waiting Active',
	    self::STATUS_ACTIVE => 'Active',
	    self::STATUS_SUSPENDED => 'Suspended'
	);
    }

    /**
     * get type of current user
     */
    public function getType() {
	
    }

    /**
     * get avatar url of current user
     * allow size: small, thumb, medium, large, full
     * if user is logon with social provider, return url of social provider
     * @param string $size small, thumbnail, medium, large, full
     */
    public function getAvatarUrl($size = 'thumb') {
	preg_match('/.+(?=\?)/', $this->avatar, $match);

	if ($match) {
	    switch ($size) {
		case 'thumb' :
		    $width = 200;
		    $height = 150;
		    break;
		case 'small' :
		    $width = 64;
		    $height = 64;
		    break;
		case 'large':default :
		    $width = 800;
		    $height = 600;
		    break;
	    }
	    return $match[0] . '?width=' . $width . '&height=' . $height;
	} else {
	    switch ($size) {
		case 'thumb' :
		    $width = 200;
		    $height = 150;
		    break;
		case 'small' :
		    $width = 64;
		    $height = 64;
		    break;
		case 'large':
		    $width = 800;
		    $height = 600;
		    break;
		case 'full': default :
		    return UPLOAD_URL . 'avatar/' . $this->avatar;
		    break;
	    }
	}

	if ($this->avatar == '' && $this->social_provider == '') {
	    //empty
	    $avatar = 'default.png';
	} else {
	    $avatar = $this->avatar;
	}

	return ImageHelper::thumb($width, $height, 'avatar' . DIRECTORY_SEPARATOR . $avatar);
    }

    /**
     * get range of gender
     * @return array key => value
     */
    public static function getGenderRange() {
	return array(
	    self::GENDER_MALE => '<img src="' . WWW_URL . 'images/img_14.png" />',
	    self::GENDER_FEMALE => '<img src="' . WWW_URL . 'images/img_16.png" />'
	);
    }

    /**
     * get range of gender
     * @return array key => value
     */
    public static function getGenderRangeAdmin() {
	return array(
	    self::GENDER_MALE => 'Male',
	    self::GENDER_FEMALE => 'Female'
	);
    }

    /**
     *
     * @return type
     */
    public static function getTypeRange() {
	return array(
	    self::TYPE_MEMBER => 'Member',
	    self::TYPE_ADMIN => 'Admin',
	    self::TYPE_SUPER_ADMIN => 'Super Admin'
	);
    }

    /**
     * For sign in with social
     * @param type $email
     * @return type
     */
    public function findByEmail($email) {
	return self::model()->findByAttributes(array('email' => $email));
    }

    /**
     * 
     */
    public function getSomeMember($limit) {
	return self::model()->findAll(array(
		    "condition" => "status=" . User::STATUS_ACTIVE . " and type=''",
		    "order" => "rand()",
		    "limit" => $limit
	));
    }

    public function checkFriend($userId, $displayName) {
	$aFriends = Yii::app()->cache->get('aFriends');
	if ($aFriends === false) {
	    $aFriends = array();
	    /*
	     * get all friend and make it to array
	     */
	    $modelFriend = Friend::model()->findAll(array(
		"condition" => "t.user_id = " . user()->id
	    ));
	    foreach ($modelFriend as $friend) {
		$aFriends[$friend->friend_user_id] = $friend->friend_user_id;
	    }
	    Yii::app()->cache->set('aFriends', $aFriends, 15);
	}
	$aPersonSent = Yii::app()->cache->get('aPersonSent');
	if ($aPersonSent === false) {
	    $aPersonSent = array();
	    /*
	     * get all person that self sent requestand make it to array
	     */
	    $modelFriendRequest = FriendRequest::model()->findAll(array(
		"condition" => "t.user_send = " . user()->id
	    ));
	    foreach ($modelFriendRequest as $request) {
		$aPersonSent[$request->user_receive] = $request->user_receive;
	    }
	    Yii::app()->cache->set('aPersonSent', $aPersonSent, 15);
	}
	if (array_search($userId, $aFriends)) {
	    return '<img alt="chat" title="Chat" class="chat-with chat-in-dis" src="' . WWW_URL . 'img/chat-with.png" id-user="' . $userId . '" user-name="' . substr($displayName, 0, 10) . '"/>';
	} else {
	    if (array_search($userId, $aPersonSent)) {
		
	    } else {
		return '<img alt="add friend" title="Add friend" class="add-friend add-friend-in-dis invite-id-' . $userId . '" user-receive="' . $userId . '" src="' . WWW_URL . 'img/addfriend.png"/>';
	    }
	}
    }

    /*     * *************
     * information of user
     */

    ////Marital status
    public static function getListMarital() {
	return array(
	    '' => 'Any',
	    1 => 'Never Married',
	    2 => 'Legally Separated',
	    3 => 'Divorced',
	    4 => ' Widowed'
	);
    }

    ////Ethnicity
    public static function getListEthnicity() {
	return array(
	    '' => 'Any',
	    1 => ' Asian',
	    2 => 'Black / African descent',
	    3 => 'East Indian',
	    4 => 'Latino / Hispanic',
	    5 => 'Middle Eastern',
	    6 => 'Native American',
	    7 => 'Pacific Islander',
	    8 => 'White / Caucasian',
	    9 => 'Other'
	);
    }

    ////Relationship
    public static function getListRelationship() {
	return array(
	    '' => 'Any',
	    1 => 'Marriage',
	    2 => 'Serious Relationship',
	    3 => 'Travel Partner',
	    4 => 'Casual Relationship',
	    5 => 'Pen Pal',
	);
    }

    ////Relationship Expectations
    public static function getListZodiac() {
	return array(
	    '' => 'Any',
	    1 => 'Aries',
	    2 => 'Taurus',
	    3 => 'Gemini',
	    4 => 'Cancer',
	    5 => 'Leo',
	    6 => 'Virgo',
	    7 => 'Libra',
	    8 => 'Scorpio',
	    9 => 'Sagittarius',
	    10 => 'Capricorn',
	    11 => 'Aquarius',
	    12 => 'Pisces'
	);
    }

    ////Smoking Preference
    public static function getListSmoking() {
	return array(
	    '' => 'Any',
	    1 => 'Non-Smoker',
	    2 => 'Social Smoker',
	    3 => 'Daily Smoker'
	);
    }

    ////Height
    public static function getListHeight() {
	$label = 4;
	$j = 0;
	for ($i = 1; $i <= 48; $i++) {
	    $aHeights[$i] = $label . "' " . $j;
	    $j++;
	    if ($i != 0 && $i % 12 == 0) {
		$label++;
		$j = 0;
	    }
	}
	return $aHeights;
    }

    ////General Build
    public static function getListBuild() {
	return array(
	    '' => 'Any',
	    1 => 'no answer',
	    2 => 'Slender',
	    3 => 'About average',
	    4 => 'Athletic and Toned',
	    5 => 'A few extra pounds',
	    6 => 'Heavyset',
	    7 => 'Stocky'
	);
    }

    ////Children
    public static function getListChildren() {
	return array(
	    1 => 'Yes',
	    '' => 'No'
	);
    }

    ////Religion
    public static function getListReligion() {
	return array(
	    '' => 'Any',
	    1 => 'Agnostic',
	    2 => 'Atheist',
	    3 => 'Buddhist',
	    4 => 'Catholic',
	    5 => 'Christian',
	    6 => 'Hindu',
	    7 => 'Jewish',
	    8 => 'LDS',
	    9 => 'Muslim',
	    10 => 'Other',
	);
    }

    ////age
    public static function getListAge() {
	$aAges = array();
	for ($i = 18; $i <= 100; $i++) {
	    $aAges[$i] = $i;
	}
	return $aAges;
    }

    /**
     * get button send message
     */
    public function getBtnSendMsg() {
	if (time() > user()->getModel()->expired_time_msg) {
	    $btn = '<a class="show-box-msg" href="' . url('paypal') . '" title="Send message"><i class="icon-envelope"></i></a>';
	} else {
	    $btn = '<a class="show-box-msg" href="#box-msg-' . $this->user_id . '" title="Send message"><i class="icon-envelope"></i></a>';
	    $btn .= '
<div aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" class="modal hide fade" id="box-msg-' . $this->user_id . '">
    <div class="modal-header">
	<button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button>
	<h3 id="myModalLabel">Send message to "' . $this->username . '"</h3>
    </div>
    <form method="post" action="" enctype="multipart/formdata" class="form-msg">
	<div class="modal-body">
	    <div class="announce"></div>	    
	    <input type="hidden" value="' . $this->username . '" name="Mailbox[to]">
	    <input type="text" placeholder="Subject" name="Mailbox[subject]" style="width: 97.2%;" class="subject-mg">
	    <textarea placeholder="Enter message here..." name="Message[text]" style="margin: 0px 0px 10px; width: 516px; height: 101px;" class="message-mg"></textarea>
	</div>
	<div class="modal-footer">
	    <button aria-hidden="true" data-dismiss="modal" class="btn">Close</button>
	    <input type="submit" id="send-msg" name="send-msg" value="Send" class="btn btn-primary">
	</div>
    </form>
</div>';
	}
	return $btn;
    }

    /**
     * get button chat
     */
    public function getBtnChat() {
	return '<img user-name="' . $this->username . '" id-user="' . $this->user_id . '" src="' . WWW_URL . 'img/chat-with.png" class="chat-with" title="Chat" alt="chat"/>';
    }

    /**
     * get username
     */
    public function getUserName() {
	return '<a class="user-name" href="' . url('/user/' . $this->user_id) . '">' . $this->username . '</a>';
    }

    /**
     * get button flirt
     */
    public function getBtnFlirt() {

	if (array_search($this->user_id, Flirt::getList(user()->id)) === FALSE) {
	    return '<img title="Flirt" alt="flirt" src="' . WWW_URL . '/img/icon-flirt.png" class="flirt-user img-flirt" receiver="' . $this->user_id . '"/>';
	} else {
	    return '';
	}
    }

    /**
     * search user on Frontend page
     */
    public function searchFront($type) {
	$criteria = new CDbCriteria();
	if ($type == 'forMatches') {
	    /**
	     * for show matches
	     */
	    if (user()->getModel()->ideal_profile) {
		foreach (user()->getModel()->ideal_profile as $key => $value) {
		    if ($value != null && $value) {
			if ($key != 'age_from' && $key != 'age_to' && $key != 'height_from' && $key != 'height_to')
			    $criteria->addCondition('t.' . $key . '=' . $value);
			else {
			    if ($key == 'age_from') {
				$criteria->addCondition('t.age Between ' . $value . ' and ' . user()->getModel()->ideal_profile['age_to']);
			    } else {
				if ($key == 'height_from')
				    $criteria->addCondition('t.height Between ' . $value . ' and ' . user()->getModel()->ideal_profile['height_to']);
			    }
			}
		    }
		}
	    }

	    $criteria->addCondition('t.postcode = ' . user()->getModel()->postcode . ' AND t.gender != "' . user()->getModel()->gender . '"');
	    $criteria->addCondition('t.user_id != ' . user()->id);
	}elseif ($type == 'forOnline') {
	    /**
	     * for show someone is onlining
	     */
	    $timeOnline = time() - 30;
	    $criteria->addCondition('t.last_online >= ' . $timeOnline);
	    $criteria->addCondition('t.user_id != ' . user()->id);
	} elseif ($type == 'forBirth') {
	    /**
	     * for someone has birthday today
	     */
	    $day = date('d', time());
	    $month = date('m', time());
	    $criteria->addCondition('DAY(birthday) = ' . $day . ' AND MONTH(birthday) =' . $month);
	    $criteria->addCondition('t.user_id != ' . user()->id);
	}
	$criteria->compare('username', $this->username, true);
	return new CActiveDataProvider($this, array(
	    'criteria' => $criteria,
	    'pagination' => array(
		'pageSize' => param('pageSize')
	    ),
	    'sort' => array(
		'defaultOrder' => array(
		    'user_id' => CSort::SORT_DESC
		)
	    )
	));
    }

}

